<!--
/**
 * @Author: 林中奇
 * @Date: 2020/12/15
 * @lastAuthor:
 * @lastChangeDate:
 * @Explain: 点击验证
 * @ChildComponents:
 */ -->
<template>
  <div style="position: relative">
    <div class="verify-img-out">
      <div class="verify-img-panel" :style="{
          width: setSize.imgWidth,
          height: setSize.imgHeight,
          'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
          'margin-bottom': space + 'px'
        }">
        <div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
          <i class="iconfont icon-refresh"></i>
        </div>
        <img :src="pointBackImgBase" ref="canvas" alt style="width:100%;height:100%;display:block"
          @click="bindingClick ? canvasClick($event) : undefined" />

        <div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area" :style="{
            'background-color': '#1abd6c',
            color: '#fff',
            'z-index': 9999,
            width: '20px',
            height: '20px',
            'text-align': 'center',
            'line-height': '20px',
            'border-radius': '50%',
            position: 'absolute',
            top: parseInt(tempPoint.y - 10) + 'px',
            left: parseInt(tempPoint.x - 10) + 'px'
          }">{{ index + 1 }}</div>
      </div>
    </div>
    <div class="verify-bar-area" :style="{
        width: setSize.imgWidth,
        color: this.barAreaColor,
        'border-color': this.barAreaBorderColor,
        'line-height': barHeight
      }">
      <span class="verify-msg">{{ text }}</span>
    </div>
  </div>
</template>
<script>
/**
 * VerifyPoints
 * @description 点选
 */

import { resetSize } from '@/utils/util'
import { rsaEncrypt } from '@/utils/index.js'

export default {
  name: 'VerifyPoints',
  props: {
    //弹出式pop，固定fixed
    mode: {
      type: String,
      default: 'fixed'
    },
    // 默认的文字数量
    defaultNum: {
      type: Number,
      default: 7
    },
    // 校对的文字数量
    checkNum: {
      type: Number,
      default: 3
    },
    //间隔
    space: {
      type: Number,
      default: 5
    },
    imgSize: {
      type: Object,
      default() {
        return {
          width: '310px',
          height: '155px'
        }
      }
    },
    // 滑块高度
    barHeight: {
      type: String,
      default: '40px'
    }
  },
  data() {
    return {
      uuId: '',
      fontPos: [], // 选中的坐标信息
      checkPosArr: [], //用户点击的坐标
      num: 1, //点击的记数
      pointBackImgBase: '', //后端获取到的背景图片
      setSize: {
        imgHeight: 0,
        imgWidth: 0,
        barHeight: 0,
        barWidth: 0
      },
      tempPoints: [],
      text: '',
      barAreaColor: undefined,
      barAreaBorderColor: undefined,
      showRefresh: true,
      bindingClick: true,
      original: {
        width: 310,
        height: 155
      }, // 图像原始尺寸
      // 单位判断使用util.js
      barSize: {
        width: '310px',
        height: '40px'
      }
    }
  },
  computed: {
    resetSize() {
      return resetSize
    }
  },
  methods: {
    init() {
      //加载页面
      this.fontPos.splice(0, this.fontPos.length)
      this.checkPosArr.splice(0, this.checkPosArr.length)
      this.num = 1
      this.getPictrue()

      this.$nextTick(() => {
        this.setSize = this.resetSize(this) //重新设置宽度高度
        this.$emit('ready', this)
      })
    },
    canvasClick(e) {
      this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e))
      if (this.num == this.checkNum) {
        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
        //按比例转换坐标值
        this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize)

        //等创建坐标执行完
        setTimeout(async () => {
          //发送后端请求
          let data = {
            captchaType: 1,
            checkJson: rsaEncrypt(this.checkPosArr),
            uuId: this.uuId
          }
          const res = await this.$api.verify.check(data)
          if (res) {
            this.barAreaColor = '#4cae4c'
            this.barAreaBorderColor = '#5cb85c'
            this.text = '验证成功'
            this.showRefresh = false
            this.bindingClick = false
            if (this.mode == 'pop') {
              setTimeout(() => {
                this.$parent.clickShow = false
                this.refresh()
              }, 1500)
            }
            this.$emit('success', true)
          } else {
            this.$emit('error', false)
            this.barAreaColor = '#d9534f'
            this.barAreaBorderColor = '#d9534f'
            this.text = '验证失败'
            setTimeout(() => {
              this.refresh()
            }, 700)
          }
        }, 400)
      }

      if (this.num < this.checkNum) {
        this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
      }
    },
    //获取坐标
    getMousePos: function (obj, e) {
      const x = e.offsetX
      const y = e.offsetY
      return { x, y }
    },
    //创建坐标点
    createPoint: function (pos) {
      this.tempPoints.push(Object.assign({}, pos))
      return ++this.num
    },
    refresh: function () {
      this.tempPoints.splice(0, this.tempPoints.length)
      this.barAreaColor = '#000'
      this.barAreaBorderColor = '#ddd'
      this.bindingClick = true

      this.fontPos.splice(0, this.fontPos.length)
      this.checkPosArr.splice(0, this.checkPosArr.length)
      this.num = 1

      this.getPictrue()
      this.showRefresh = true
    },

    // 请求背景图片和验证图片
    async getPictrue() {
      const res = await this.$api.verify.getPicture({ type: 1 })
      if (res) {
        this.pointBackImgBase = res.bgCanvas
        this.text = '请依次点击【' + res.words + '】'
        this.original = res.size
        this.uuId = res.uuId
      }
    },
    //坐标转换函数
    pointTransfrom(pointArr, imgSize) {
      var newPointArr = pointArr.map(p => {
        let x = Math.round((this.original.width * p.x) / parseInt(imgSize.imgWidth))
        let y = Math.round((this.original.height * p.y) / parseInt(imgSize.imgHeight))
        return { x, y }
      })
      return newPointArr
    }
  },
  watch: {
    // type变化则全面刷新
    type: {
      immediate: true,
      handler() {
        this.init()
      }
    }
  },
  mounted() {
    // 禁止拖拽
    this.$el.onselectstart = function () {
      return false
    }
  }
}
</script>
